package net.NingXiaRuiTai.ShortChain.interceptor;

import com.alibaba.cloud.commons.lang.StringUtils;
import feign.Request;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import net.NingXiaRuiTai.ShortChain.enums.BizCodeEnum;
import net.NingXiaRuiTai.ShortChain.model.LoginUser;
import net.NingXiaRuiTai.ShortChain.utils.CommonUtil;
import net.NingXiaRuiTai.ShortChain.utils.JsonData;
import net.NingXiaRuiTai.ShortChain.utils.JwtUtil;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
//    声明一个ThreadLocal对象，用于存储线程局部变量。
    public static  ThreadLocal<LoginUser> threadLocal = new ThreadLocal<>();
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //检查当前HTTP请求的方法是否为OPTIONS。
        //OPTIONS请求在跨域资源共享（CORS）场景中非常常见。
        // 当浏览器发起跨域请求时，它会首先发送一个OPTIONS请求，
        // 以检查服务器是否允许该跨域请求。
        // 服务器会在响应中包含Access-Control-Allow-Methods和Access-Control-Allow-Headers等头信息，
        // 以告知浏览器哪些方法和头信息是允许的。
        if(Request.HttpMethod.OPTIONS.toString().equals(request.getMethod())){
            //返回体中设置的状态码为204，表示没有内容。
           response.setStatus(HttpStatus.NO_CONTENT.value());
       }
        //从请求头中获取名为token。
        String accessToken = request.getHeader("token");
        //如果token为空，从请求参数中获取名为token。
        if (StringUtils.isBlank(accessToken)){
            accessToken=request.getParameter("token");

        }

        //如果token不为空，检查token的有效性。
        if(StringUtils.isNotBlank(accessToken)){
            Claims claims = JwtUtil.checkJWT(accessToken);
            if (claims==null){
                //未登录
                 CommonUtil.sendJsonMessage(response, JsonData.buildResult(BizCodeEnum.ACCOUNT_UNLOGIN));
                return false;
            }
            long accountNo = Long.parseLong(claims.get("accountNo").toString());
            String headImg = (String)claims.get("headImg");
            String username=(String)claims.get("username");
            String phone=(String)claims.get("phone");
            String email=(String)claims.get("mail");
            String auth=(String)claims.get("auth");
            LoginUser loginUser = new LoginUser().builder()
                    .headImg(headImg)
                    .mail(email)
                    .auth(auth)
                    .phone(phone)
                    .username(username)
                    .accountNo(accountNo)
                    .build();

            //将登录用户信息存储到请求属性中，以便后续使用。
//            request.setAttribute("loginUser",loginUser);

            //将登录用户信息存储到线程局部变量中，以便后续使用。
            log.info("将登录用户信息存入threadLocal中:{}",loginUser);
            threadLocal.set(loginUser);
            //返回true，表示请求可以继续处理。

            return true;


        }

        CommonUtil.sendJsonMessage(response,JsonData.buildResult(BizCodeEnum.ACCOUNT_UNLOGIN));
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //释放线程局部变量
        threadLocal.remove();
    }
}
